package com.dhecp.project.flowable.service.impl;

import com.dhecp.common.core.domain.AjaxResult;
import com.dhecp.common.utils.MessageUtils;
import com.dhecp.common.utils.StringUtils;
import com.dhecp.core.constant.FlowableConstant;
import com.dhecp.framework.util.ShiroUtils;
import com.dhecp.project.flowable.domain.*;
import com.dhecp.project.flowable.extend.CustomProcessDiagramGenerator;
import com.dhecp.project.flowable.juel.ActAuthService;
import com.dhecp.project.flowable.mapper.ActProcessMapper;
import com.dhecp.project.flowable.mapper.SysProcessInstanceMapper;
import com.dhecp.project.flowable.service.ActProcessDefinitionService;
import com.dhecp.project.flowable.service.ActProcessService;
import com.dhecp.project.system.domain.SysDictionaryForModule;
import com.dhecp.project.system.mapper.SysDictionaryForModuleMapper;
import com.dhecp.project.system.mapper.SysUserInfoMapper;
import org.flowable.bpmn.model.*;
import org.flowable.engine.*;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.impl.RepositoryServiceImpl;
import org.flowable.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.repository.ProcessDefinitionQuery;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.image.ProcessDiagramGenerator;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.InputStream;
import java.util.*;

/**
 * @ClassName ActProcessServiceImpl
 * @Description TODO
 * @Author alula
 * @Date 2020-04-01 14:57
 */
@Service
public class ActProcessServiceImpl implements ActProcessService {

    @Autowired
    private SysProcessInstanceMapper sysProcessInstanceMapper;

    @Autowired
    private ActProcessMapper actProcessMapper;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private IdentityService identityService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private SysUserInfoMapper sysUserInfoMapper;

    @Autowired
    private SysDictionaryForModuleMapper sysDictionaryForModuleMapper;

    @Autowired
    private ActProcessDefinitionService actProcessDefinitionService;

    @Override
    public List<ActRuntimeInstance> queryActRuntimeProcess(Map<String, Object> params) {
        params.put("assignee", ShiroUtils.getMandatorId());
        return actProcessMapper.findActRuntimeProcess2(params);
    }

    @Override
    public List<ActHistoricInstance> queryActFinishProcess(Map<String, Object> params) {
        params.put("assignee", ShiroUtils.getMandatorId());
        return actProcessMapper.findActFinishProcess(params);
    }

    @Override
    public List<ActHistoricActivity> queryActHistoricActivityByProcInstId(String processInstanceId) {
        Map<String, Object> params = new HashMap<>();
        params.put("procInstId", processInstanceId);
        List<ActHistoricActivity> activityList = actProcessMapper.findActHistoricActivityByProcInstId(params);
        return activityList;
    }

    @Override
    public AjaxResult startProcess(SysProcessInstance sysProcessInstance) {
        if (StringUtils.isEmpty(sysProcessInstance.getProcDefKey())) {
            return AjaxResult.error(MessageUtils.message("module.error.paramnotempty", "ProcDefKey"));
        }
        if (StringUtils.isEmpty(sysProcessInstance.getTableDataId())) {
            return AjaxResult.error(MessageUtils.message("module.error.paramnotempty", "TableDataId"));
        }
        if (StringUtils.isEmpty(sysProcessInstance.getProcessTitle())) {
            return AjaxResult.error(MessageUtils.message("module.error.paramnotempty", "ProcessTitle"));
        }
        String businessKey = UUID.randomUUID().toString();
        identityService.setAuthenticatedUserId(ShiroUtils.getMandatorId());
        Map<String, Object> variables = sysProcessInstance.getParams();
        if (variables == null) {
            variables = new HashMap<String, Object>();
        }
        //注册Juel表达式类
        variables.put("authService", new ActAuthService());
        variables.put("moduleKey", sysProcessInstance.getProcDefKey());
        variables.put("tableDataId", sysProcessInstance.getTableDataId());
        variables.put("currentUserId", ShiroUtils.getMandatorId());
        //test
        //List<String> assigneeList = new ArrayList<>();
        //assigneeList.add("test2");
        //assigneeList.add("test3");
        //variables.put("assigneeList", assigneeList);
        ProcessDefinition processDefinition = actProcessDefinitionService.queryActProcessDefinitionByKey(sysProcessInstance.getProcDefKey());
        if(processDefinition == null){
            return AjaxResult.error(MessageUtils.message("flowable.definition.error.defexistsfail"));
        }
        ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId(), businessKey, variables);
        String processInstanceId = processInstance.getId();
        sysProcessInstance.setGuid(businessKey);
        sysProcessInstance.setProcInstId(processInstanceId);
        sysProcessInstance.setProcDefId(processInstance.getProcessDefinitionId());
        sysProcessInstance.setProcDefKey(processInstance.getProcessDefinitionKey());
        //取流程定义信息
        sysProcessInstance.setProcDefName(processDefinition.getName());
        sysProcessInstance.setProcDefVersion(processDefinition.getVersion());
        sysProcessInstance.setProcDeplId(processDefinition.getDeploymentId());

        //查询这个实例运行中的任务
        List<Task> taskList = taskService.createTaskQuery().processInstanceId(processInstanceId).list();
        //启动时设置首个任务信息
        for(Task task : taskList){
            sysProcessInstance.setNextTaskId(task.getId());
            sysProcessInstance.setNextActId(task.getTaskDefinitionKey());
            sysProcessInstance.setNextActAlias(task.getTaskDefinitionKey());
            // 设置任务优先级为1
            taskService.setPriority(task.getId(), 1);
            //删除制单环节在设计器中设置的候选人、候选组等配置
            deleteFirstSegmentUserExpression(task);
            taskService.setAssignee(task.getId(), ShiroUtils.getMandatorId());
        }
        //发起人
        sysProcessInstance.setCreateUser(ShiroUtils.getMandatorId());
        sysProcessInstance.setOrganizer(ShiroUtils.getMandatorId());
        sysProcessInstance.setOrganizerName(ShiroUtils.getMandatorName());
        sysProcessInstance.setStartFlowTime(new Date());
        SysDictionaryForModule sysDictionaryForModule = sysDictionaryForModuleMapper.findDictionaryForModuleByModuleTable(sysProcessInstance.getProcDefKey());
        if (sysDictionaryForModule != null){
            String routeName = (!StringUtils.isEmpty(sysDictionaryForModule.getModuleAlias()) ? sysDictionaryForModule.getModuleAlias() : sysDictionaryForModule.getModuleName());
            sysProcessInstance.setRouteUrl(sysDictionaryForModule.getModuleurl2());
            sysProcessInstance.setRouteName(routeName);
        }
        sysProcessInstanceMapper.insert(sysProcessInstance);
        return new AjaxResult(AjaxResult.Type.SUCCESS, MessageUtils.message("module.success.issuccess"), processInstanceId);

    }

    @Override
    public AjaxResult resetProcess(String nid) {
        if (StringUtils.isEmpty(nid)) {
            return AjaxResult.error(MessageUtils.message("module.error.paramnotempty", "nid"));
        }
        SysProcessInstance sysProcessInstance = sysProcessInstanceMapper.findSysProcessInstanceByTableDataId(nid);
        if (sysProcessInstance == null){
            return AjaxResult.error(MessageUtils.message("flowable.process.error.instanceobjectfail"));
        }
        //重置时，删除原来旧的流程历史
        try{
            historyService.deleteHistoricProcessInstance(sysProcessInstance.getProcInstId());
        }catch (Exception ex){
        }
        String businessKey = sysProcessInstance.getGuid();
        String assignee = sysProcessInstance.getOrganizer();
        identityService.setAuthenticatedUserId(assignee);
        Map<String, Object> variables = sysProcessInstance.getParams();
        if (variables == null) {
            variables = new HashMap<String, Object>();
        }
        //注册Juel表达式类
        variables.put("authService", new ActAuthService());
        variables.put("moduleKey", sysProcessInstance.getProcDefKey());
        variables.put("tableDataId", sysProcessInstance.getTableDataId());
        variables.put("currentUserId", assignee);

        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(sysProcessInstance.getProcDefKey(), businessKey, variables);
        String processInstanceId = processInstance.getId();
        sysProcessInstance.setProcInstId(processInstanceId);
        sysProcessInstance.setProcDefId(processInstance.getProcessDefinitionId());
        sysProcessInstance.setProcDefKey(processInstance.getProcessDefinitionKey());
        //取流程定义信息
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processInstance.getProcessDefinitionId()).singleResult();
        if (processDefinition != null){
            sysProcessInstance.setProcDefName(processDefinition.getName());
            sysProcessInstance.setProcDefVersion(processDefinition.getVersion());
            sysProcessInstance.setProcDeplId(processDefinition.getDeploymentId());
        }
        //查询这个实例运行中的任务
        List<Task> taskList = taskService.createTaskQuery().processInstanceId(processInstanceId).list();
        //启动时设置首个任务信息
        for(Task task : taskList){
            sysProcessInstance.setPrevTaskId("");
            sysProcessInstance.setPrevActId("");
            sysProcessInstance.setNextTaskId(task.getId());
            sysProcessInstance.setNextActId(task.getTaskDefinitionKey());
            sysProcessInstance.setNextActAlias(task.getTaskDefinitionKey());
            // 设置任务优先级为1
            taskService.setPriority(task.getId(), 1);
            //删除制单环节在设计器中设置的候选人、候选组等配置
            deleteFirstSegmentUserExpression(task);
            taskService.setAssignee(task.getId(), assignee);
        }
        //重置流程设置
        sysProcessInstance.setStartFlowTime(new Date());
        sysProcessInstance.setDataStatus(0);
        sysProcessInstance.setResultStatus(0);
        sysProcessInstance.setUpdateUser(ShiroUtils.getMandatorId());
        sysProcessInstance.setUpdateTime(new Date());
        sysProcessInstance.setActComment("");
        sysProcessInstance.setActFuncKey("");
        sysProcessInstance.setActFormPage("");
        sysProcessInstance.setActFuncIsEdit(false);
        sysProcessInstanceMapper.updateResetProcess(sysProcessInstance);
        return new AjaxResult(AjaxResult.Type.SUCCESS, MessageUtils.message("module.success.issuccess"), processInstanceId);
    }

    @Override
    public AjaxResult deleteProcess(String proInsId) {
        if (StringUtils.isEmpty(proInsId)) {
            return AjaxResult.error(MessageUtils.message("module.error.paramfail", proInsId));
        }
        ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(proInsId).singleResult();
        if (pi == null){
            return AjaxResult.error(MessageUtils.message("flowable.process.error.instanceobjectfail"));
        }
        runtimeService.deleteProcessInstance(pi.getId(), FlowableConstant.DELETE_PRE + "单据级联删除");
        historyService.deleteHistoricProcessInstance(pi.getId());
        sysProcessInstanceMapper.deleteSysProcessInstanceByGuid(pi.getBusinessKey());
        return AjaxResult.success(MessageUtils.message("module.success.issuccess"));
    }

    @Override
    public AjaxResult updateProcessInstanceStatus(String proInsId, int status) {
        if (StringUtils.isEmpty(proInsId)) {
            return AjaxResult.error(MessageUtils.message("module.error.paramfail", proInsId));
        }
        ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(proInsId).singleResult();
        if (pi == null){
            return AjaxResult.error(MessageUtils.message("flowable.process.error.instanceobjectfail"));
        }
        if(status == 1){
            runtimeService.activateProcessInstanceById(proInsId);
        }else if(status == 0){
            runtimeService.suspendProcessInstanceById(proInsId);
        }
        return AjaxResult.success(MessageUtils.message("module.success.issuccess"));
    }

    @Override
    public InputStream getActivitiProccessImage(String processInstanceId) {
        InputStream imageStream = null;
        try {
            HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
            if (hpi != null) {
                ProcessDefinitionQuery pdq = repositoryService.createProcessDefinitionQuery();
                ProcessDefinition pd = pdq.processDefinitionId(hpi.getProcessDefinitionId()).singleResult();// pdq.processDefinitionKey("leave").singleResult();
                String resourceName = pd.getDiagramResourceName();
                if (resourceName.endsWith(".png") && StringUtils.isEmpty(processInstanceId) == false) {
                    HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
                    if (historicProcessInstance == null) {
                        //throw new BusinessException("获取流程实例ID[" + pProcessInstanceId + "]对应的历史流程实例失败！");
                    } else {
                        // 通过流程实例ID获取历史流程实例
                        // 通过流程实例ID获取流程中已经执行的节点，按照执行先后顺序排序
                        List<HistoricActivityInstance> historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).orderByHistoricActivityInstanceId().asc().list();
                        // 将已经执行的节点ID放入高亮显示节点集合
                        List<String> highLightedActivitiIdList = new ArrayList<>();
                        for (HistoricActivityInstance historicActivityInstance : historicActivityInstanceList) {
                            if (!historicActivityInstance.getActivityType().contains("sequenceFlow")) {
                                highLightedActivitiIdList.add(historicActivityInstance.getActivityId());
                            }
                            //logger.info("已执行的节点[{}-{}-{}-{}]", historicActivityInstance.getId(), historicActivityInstance.getActivityId(), historicActivityInstance.getActivityName(), historicActivityInstance.getAssignee());
                        }
                        // 通过流程实例ID获取流程中正在执行的节点
                        List<Execution> runningActivityInstanceList = runtimeService.createExecutionQuery().processInstanceId(processInstanceId).list();
                        ;
                        List<String> runningActivitiIdList = new ArrayList<String>();
                        for (Execution execution : runningActivityInstanceList) {
                            if (!StringUtils.isEmpty(execution.getActivityId())) {
                                runningActivitiIdList.add(execution.getActivityId());
                                //logger.info("执行中的节点[{}-{}-{}]", execution.getId(), execution.getActivityId(), execution.getName());
                            }
                        }

                        // 通过流程实例ID获取已经完成的历史流程实例
                        List<HistoricProcessInstance> historicFinishedProcessInstanceList = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).finished().list();

                        // 定义流程画布生成器
                        ProcessDiagramGenerator processDiagramGenerator = null;
                        // 如果还没完成，流程图高亮颜色为绿色，如果已经完成为红色
                        // if (!CollectionUtils.isEmpty(historicFinishedProcessInstanceList)) {
                        // // 如果不为空，说明已经完成
                        // processDiagramGenerator = processEngineConfiguration.getProcessDiagramGenerator();
                        // } else {
                        processDiagramGenerator = new CustomProcessDiagramGenerator();
                        // }

                        // 获取流程定义Model对象
                        BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());

                        // 获取已流经的流程线，需要高亮显示高亮流程已发生流转的线id集合
                        List<String> highLightedFlowIds = getHighLightedFlows(bpmnModel, historicActivityInstanceList);

                        // 使用默认配置获得流程图表生成器，并生成追踪图片字符流
                        imageStream = ((CustomProcessDiagramGenerator) processDiagramGenerator)
                                .generateDiagramCustom(bpmnModel, "png",
                                        highLightedActivitiIdList, runningActivitiIdList, highLightedFlowIds,
                                        "黑体", "黑体", "黑体",
                                        null, 2.0);
                    }
                } else {
                    // 通过接口读取
                    imageStream = repositoryService.getResourceAsStream(pd.getDeploymentId(), resourceName);
                }
            }
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
        return imageStream;
    }

    @Override
    public int insertActHiIdentityLink(String id, String type, String userId, String taskId, String procInstId) {
        Map<String, Object> params = new HashMap<>();
        params.put("id", id);
        params.put("type", type);
        params.put("userId", userId);
        params.put("taskId", taskId);
        params.put("procInstId", procInstId);
        return actProcessMapper.insertActHiIdentityLink(params);
    }

    @Override
    public AjaxResult updateSysProcessToBusinessData(String tableDataId, String processRemark, String corpNo, String corpName) {
        if (StringUtils.isEmpty(tableDataId)) {
            return AjaxResult.error(MessageUtils.message("module.error.paramfail", tableDataId));
        }
        Map<String, Object> params = new HashMap<>();
        params.put("tableDataId", tableDataId);
        params.put("processRemark", processRemark);
        params.put("corpNo", corpNo);
        params.put("corpName", corpName);
        int count = sysProcessInstanceMapper.updateSysProcessToBusinessData(params);
        if(count > 0){
            return AjaxResult.success(MessageUtils.message("module.success.issuccess"));
        }
        return AjaxResult.error(MessageUtils.message("module.error.iserror"));
    }

    //删除制单环节在设计器中设置的候选人、候选组等配置
    @Override
    public void deleteFirstSegmentUserExpression(Task task) {
        ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl)repositoryService).getDeployedProcessDefinition(task.getProcessDefinitionId());
        if(processDefinition  != null) {
            //清空首环节候选人、候选组、特殊审批人表达式配置
            org.flowable.bpmn.model.Process process = repositoryService.getBpmnModel(processDefinition.getId()).getMainProcess();
            FlowElement flowElement = (FlowElement) process.getFlowElement(task.getTaskDefinitionKey(), true);
            if(flowElement != null){
                if (flowElement instanceof UserTask) {
                    UserTask userTask = (UserTask) flowElement;
                    if(userTask != null){
                        userTask.setCandidateGroups(null);
                        userTask.setCandidateUsers(null);
                        userTask.setFormKey("");
                    }
                }
            }
            //删除已触发生成的人员
            actProcessMapper.deleteActTaskIdentityLink(task.getId());
        }
    }

    //获取高亮的FLOW
    protected List<String> getHighLightedFlows(BpmnModel bpmnModel, List<HistoricActivityInstance> historicActivityInstanceList) {
        // 已流经的流程线，需要高亮显示
        List<String> highLightedFlowIdList = new ArrayList<>();
        // 全部活动节点
        List<FlowNode> allHistoricActivityNodeList = new ArrayList<>();
        // 已完成的历史活动节点
        List<HistoricActivityInstance> finishedActivityInstanceList = new ArrayList<>();

        for (HistoricActivityInstance historicActivityInstance : historicActivityInstanceList) {
            // 获取流程节点
            if(!historicActivityInstance.getActivityType().contains("sequenceFlow")) {
                FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(historicActivityInstance.getActivityId());
                allHistoricActivityNodeList.add(flowNode);
                // 结束时间不为空，当前节点则已经完成
                if (historicActivityInstance.getEndTime() != null) {
                    finishedActivityInstanceList.add(historicActivityInstance);
                }
            }
        }

        FlowNode currentFlowNode = null;
        FlowNode targetFlowNode = null;
        HistoricActivityInstance currentActivityInstance;
        // 遍历已完成的活动实例，从每个实例的outgoingFlows中找到已执行的
        for (int k = 0; k < finishedActivityInstanceList.size(); k++) {
            currentActivityInstance = finishedActivityInstanceList.get(k);
            // 获得当前活动对应的节点信息及outgoingFlows信息
            currentFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(currentActivityInstance.getActivityId());
            // 当前节点的所有流出线
            List<SequenceFlow> outgoingFlowList = currentFlowNode.getOutgoingFlows();

            /**
             * 遍历outgoingFlows并找到已流转的 满足如下条件认为已流转：
             * 1.当前节点是并行网关或兼容网关，则通过outgoingFlows能够在历史活动中找到的全部节点均为已流转
             * 2.当前节点是以上两种类型之外的，通过outgoingFlows查找到的时间最早的流转节点视为有效流转
             * (第2点有问题，有过驳回的，会只绘制驳回的流程线，通过走向下一级的流程线没有高亮显示)
             */
            if ("parallelGateway".equals(currentActivityInstance.getActivityType()) || "inclusiveGateway".equals(
                    currentActivityInstance.getActivityType())) {
                // 遍历历史活动节点，找到匹配流程目标节点的
                for (SequenceFlow outgoingFlow : outgoingFlowList) {
                    // 获取当前节点流程线对应的下级节点
                    targetFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(outgoingFlow.getTargetRef());
                    // 如果下级节点包含在所有历史节点中，则将当前节点的流出线高亮显示
                    if (allHistoricActivityNodeList.contains(targetFlowNode)) {
                        highLightedFlowIdList.add(outgoingFlow.getId());
                    }
                }
            } else {
                /**
                 * 2、当前节点不是并行网关或兼容网关
                 * 【已解决-问题】如果当前节点有驳回功能，驳回到申请节点，
                 * 则因为申请节点在历史节点中，导致当前节点驳回到申请节点的流程线被高亮显示，但实际并没有进行驳回操作
                 */
                List<Map<String, Object>> tempMapList = new ArrayList<>();
                // 当前节点ID
                String currentActivityId = currentActivityInstance.getActivityId();
                int size = historicActivityInstanceList.size();
                boolean ifStartFind = false;
                boolean ifFinded = false;
                HistoricActivityInstance historicActivityInstance;
                // 循环当前节点的所有流出线
                // 循环所有历史节点
                for (int i = 0; i < historicActivityInstanceList.size(); i++) {
                    // // 如果当前节点流程线对应的下级节点在历史节点中，则该条流程线进行高亮显示（【问题】有驳回流程线时，即使没有进行驳回操作，因为申请节点在历史节点中，也会将驳回流程线高亮显示-_-||）
                    // if (historicActivityInstance.getActivityId().equals(sequenceFlow.getTargetRef())) {
                    // Map<String, Object> map = new HashMap<>();
                    // map.put("highLightedFlowId", sequenceFlow.getId());
                    // map.put("highLightedFlowStartTime", historicActivityInstance.getStartTime().getTime());
                    // tempMapList.add(map);
                    // // highLightedFlowIdList.add(sequenceFlow.getId());
                    // }
                    // 历史节点
                    historicActivityInstance = historicActivityInstanceList.get(i);
                    //logger.info("第【{}/{}】个历史节点-ActivityId=[{}]", i + 1, size, historicActivityInstance.getActivityId());
                    // 如果循环历史节点中的id等于当前节点id，从当前历史节点继续先后查找是否有当前节点流程线等于的节点
                    // 历史节点的序号需要大于等于已完成历史节点的序号，防止驳回重审一个节点经过两次是只取第一次的流出线高亮显示，第二次的不显示
                    if (i >= k && historicActivityInstance.getActivityId().equals(currentActivityId)) {
                        //logger.info("第[{}]个历史节点和当前节点一致-ActivityId=[{}]", i + 1, historicActivityInstance.getActivityId());
                        ifStartFind = true;
                        // 跳过当前节点继续查找下一个节点
                        continue;
                    }
                    if (ifStartFind) {
                        //logger.info("[开始]-循环当前节点-ActivityId=【{}】的所有流出线", currentActivityId);

                        ifFinded = false;
                        for (SequenceFlow sequenceFlow : outgoingFlowList) {
                            // 如果当前节点流程线对应的下级节点在其后面的历史节点中，则该条流程线进行高亮显示
                            // 【问题】
                            //logger.info("当前流出线的下级节点=[{}]", sequenceFlow.getTargetRef());
                            if (historicActivityInstance.getActivityId().equals(sequenceFlow.getTargetRef())) {
                                //logger.info("当前节点[{}]需高亮显示的流出线=[{}]", currentActivityId, sequenceFlow.getId());
                                highLightedFlowIdList.add(sequenceFlow.getId());
                                // 暂时默认找到离当前节点最近的下一级节点即退出循环，否则有多条流出线时将全部被高亮显示
                                ifFinded = true;
                                break;
                            }
                        }
                        //logger.info("[完成]-循环当前节点-ActivityId=【{}】的所有流出线", currentActivityId);
                    }
                    if (ifFinded) {
                        // 暂时默认找到离当前节点最近的下一级节点即退出历史节点循环，否则有多条流出线时将全部被高亮显示
                        break;
                    }
                }
            }

        }
        return highLightedFlowIdList;
    }
}
